﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using RxHeat.Tracing;

namespace RxHeat.Common
{
    /// <summary>
    ///     Helper extension methods for <see cref="System" />.X types
    /// </summary>
    public static class SystemExtensions
    {
        /// <summary>
        ///     Generates a string that describes the type. Good to use with generics.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static string DescribeType(this Type type)
        {
            string objectTypeName = type.Name;
            if (type.IsGenericType)
                objectTypeName = type.Name + "<" +
                                 type.GetGenericArguments()
                                     .Select(gt => gt.DescribeType())
                                     .Aggregate((p, gt) => p += "," + gt)
                                     .Trim(',') + ">";
            return objectTypeName;
        }

        /// <summary>
        ///     Generates <see cref="Thread" /> trace info string. Used to help enrich other tracing with thread context information.
        /// </summary>
        /// <seealso cref="IRxHeatTraceListner" />
        /// <seealso cref="DefaultRxHeatTraceListner" />
        /// <param name="thread">The thread.</param>
        /// <param name="key">The tracing key.</param>
        /// <returns></returns>
        public static string ToTraceString(this Thread thread, string key = null)
        {
            return String.Format("{0} (Thread {1} / {2})",
                                 key,
                                 thread.ManagedThreadId,
                                 thread.Name).Trim();
        }


        public static IEnumerable<Type> GetInheritancHierarchy(this Type type)
        {
            for (var current = type; current != null; current = current.BaseType)
                yield return current;
        }
    }
}